#pragma once

#include "Plugin/IPlugin.h"

#include <vector>
#include <string>
#include <filesystem>
#include <map>

class CORE_API PluginManager
{
  typedef IPlugin *(*CreatePluginFunc)();

public:
  PluginManager();
  ~PluginManager();

  static PluginManager &GetInstance();

  bool LoadPlugin(const std::string &name);
  bool LoadPluginDir(const std::filesystem::path &dir = GetPluginDir());

  static std::filesystem::path GetPluginDir();
  static std::string GetPluginExt();

  template <typename ...Args>
  void CallHook(Args &&...args)
  {
    for (auto &plugin : plugins) {
      plugin.second->Call<void>(std::forward<Args>(args)...);
    }
  }

  IPlugin *GetPlugin(const std::string &name);

  std::map<std::string, IPlugin *> plugins;
  
  static const std::filesystem::path s_defaultPluginDir;
private:
};